/**
 * 
 */
package fr.ece.ing4.si.mc.MonteCarlo;

import fr.ece.ing4.si.mc.gui.ResultWindow;
import fr.ece.ing4.si.mc.singleThreading.SingleMonteCarloMethod;

/**
 * @author Cesar Berezowski, Gaspard Peyrot
 *
 */
public class SingleMonteCarloController extends MonteCarloAbstract implements Runnable {

	private int z;
	private double s;
	private double x;
	private double r;
	private double drift;
	private double dt;
	private double vSqrdt;
	private double t;
	private int nSteps;
	private int nSimulations;
	private ResultWindow myView;
	private int counter;

	public SingleMonteCarloController() { }

	@Override
	public void run() {
		this.calculate();
		
	}

	/**
	 * Launch computation
	 */
	@Override
	public void calculate() {
		
		long execTime = System.currentTimeMillis(); 
		
		SingleMonteCarloMethod m = new SingleMonteCarloMethod();
		double a = m.monteCarloStandardOption(z, s, x, r, t, dt, drift, vSqrdt, nSteps, nSimulations, this);
		
		System.out.println("Calculated price : " + a);
		
		execTime = System.currentTimeMillis() - execTime;
		System.out.println("Execution time : " + execTime + "ms");
		
		myView.setValueAndTime(a, execTime);
		
	}

	/**
	 * @param callPutFlag flag for calling or putting
	 * @param s underlying price
	 * @param x strike price
	 * @param t time left to maturity
	 * @param r interest rate without risks
	 * @param b detention rate fees
	 * @param v volatility of the underlying price
	 * @param nSteps number of steps to do during calculations
	 * @param nSimulations number of simulations to do
	 * @param myView pointer on the result window from gui
	 */
	@Override
	public void build(String callPutFlag, double s, double x, double r, double t, 
			double b, double v,int nSteps, int nSimulations, ResultWindow myView) {
		
		if(callPutFlag == "c") z = 1;
		else if(callPutFlag == "p") z = -1;
		
		this.myView = myView;
		this.s = s;
		this.x = x;
		this.r = r;
		this.t = t;
		this.nSteps = nSteps;
		this.nSimulations = nSimulations;
		
		dt = t / nSteps;
		drift = ((b - Math.pow(v, 2)) / 2) * dt;
		vSqrdt = v * Math.sqrt(dt);
		
		counter = 0;
	}

	/**
	 * Update progress bar in the result window
	 */
	@Override
	public void updateProgress() {
		
		counter++;
		
		for(int k = 1; k < (nSimulations/100)+1; k++){
			if(counter == (int)(k*nSimulations)/100){
				myView.updateProgress(1);
				System.out.println(counter);
			}
		}
	}

}
